#include "CPES.h"

#define program_stream_map 0xBC
#define padding_stream 0xBE
#define private_stream_2 0xBF
#define ECM 0xF0
#define EMM 0xF1
#define program_stream_directory 0xFF
#define DSMCC_stream 0xF2
#define ITU_T_Rec_H_222_1_type_E_stream 0xF8


CPES::CPES(CDynamicArray* cDynamicArray):m_data(cDynamicArray)
{
	_parsePesHeader();
}

CPES::~CPES(void)
{
}

const char* CPES::getPayload()
{
	return m_data.m_cArray + m_nHeaderSize;
}

unsigned int CPES::getPayloadLength()
{
	if (m_nHeaderSize == 0)
		return 0;
	return m_data.m_nSize - m_nHeaderSize;
}
bool CPES::isSmallerThan(const CPES* cPes)
{
	if (m_PTS1 != cPes->m_PTS1)
		return (m_PTS1 < cPes->m_PTS1);
	if (m_PTS2 != cPes->m_PTS2)
		return (m_PTS2 < cPes->m_PTS2);
	
	return (m_PTS3 < cPes->m_PTS3);
}

void CPES::_parsePesHeader()
{
	char* cPesData = m_data.m_cArray;
	if (!(cPesData[0]==0 && cPesData[1] ==0 && cPesData[2]==1)){
		m_nHeaderSize = 0;
		return;
	}

	unsigned int stream_id = cPesData[3] & 0xff;
	unsigned int PES_packet_length = (cPesData[4]& 0xff)*(256) + (cPesData[5]& 0xff);
	if( !(stream_id != program_stream_map
		&& stream_id != padding_stream
		&& stream_id != private_stream_2
		&& stream_id != ECM
		&& stream_id != EMM
		&& stream_id != program_stream_directory
		&& stream_id != DSMCC_stream
		&& stream_id != ITU_T_Rec_H_222_1_type_E_stream)) 
	{
		m_nHeaderSize = 0;
		return;
	}

	//cPesData[6]
	//'10' 2 bslbf
	//PES_scrambling_control 2 bslbf
	//PES_priority 1 bslbf
	//data_alignment_indicator 1 bslbf
	//copyright 1 bslbf
	//original_or_copy 1 bslbf

	//cPesData[7]
	unsigned int PTS_DTS_flags = (cPesData[7] & 0xc0)/64;
	//ESCR_flag 1 bslbf
	//ES_rate_flag 1 bslbf
	//DSM_trick_mode_flag 1 bslbf
	//additional_copy_info_flag 1 bslbf
	//PES_CRC_flag 1 bslbf
	//PES_extension_flag 1 bslbf
	//cPesData[8]
	unsigned int PES_header_data_length = cPesData[8] & 0xff;
	//cPesData[9-13]
	//if (PTS_DTS_flags =='10' ) {
	//'0010' 4 bslbf
	//PTS [32..30] 3 bslbf
	//marker_bit 1 bslbf
	//PTS [29..15] 15 bslbf
	//marker_bit 1 bslbf
	//PTS [14..0] 15 bslbf
	//marker_bit 1 bslbf
	//}
	int PTS, PTS1, PTS2, PTS3;
	if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3 )
	{
		PTS1 = (cPesData[9] & 0x0e)/2;//3 bits
		PTS2 = (cPesData[10] & 0xff)*256 + (cPesData[11] & 0xfe)/2;//15 bits
		PTS3 = (cPesData[12] & 0xff)*256 + (cPesData[13] & 0xfe)/2;//15 bits
	}
	PTS = PTS1*262144 + PTS2*32768 + PTS3;

	m_nHeaderSize = 9 + PES_header_data_length;
}


bool PesSortFunction(CPES* p1, CPES* p2)
{
	return p1->isSmallerThan(p2);
}
